#include "hal.h"
#include "terminal.h"
#include "timers.h"
#include "cilindrica.h"
#include "lpc17xx_uart.h"

union_terminal gTerminal;
uint8_t	gTerminalFeedBack	=	0;
/**********************************************************************************
 * Descrição:Inicializa a funcção de terminal, a qual tem a funcionalidade de
 * receber paramentros via serial que corresponderam aos botoes de um terminal.
 *
 * Paramêtro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/
void terminal_init(void)
{
	gTerminalFeedBack	=	0;
	GPIO_SetDir(1,(uint32_t)(1<<31),1); 
	GPIO_ClearValue(1,(uint32_t)(1<<31));
	gTerminal.u16=0; //inicializa com zero todos os botoes do terminal
	gTerminal.input.velocidade1=1;
	gTerminal.input.pressao1=1;
	gTerminal.input.tempo1=1;
	uart2_init();	 //Inicializa a a uart em 57600/8bits/
}

/**********************************************************************************
 * Descrição:Realiza leitura do dado de entrada do terminal de forma realizar
 * interpretação de  byte a byte dos dados recebido via interface selecionada.
 *
 * Paramêtro(s):
 *					-	input - Informação a ser interpretada
 * Retorno:
 *					-
 **********************************************************************************/
  void terminal_read(uint32_t input){
    

          gTerminal.u16= input;
          gTerminalFeedBack	=	1;
#ifdef	_DBGFWK
          //_DBG("\rgTerminal.u16 = ");
          //_DBD(gTerminal.u16);
#endif
        
}

/**********************************************************************************
 * Descrição:
 *
 * Paramêtro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/
void terminal_feedback(void){

          union{
          uint32_t u32;
          uint8_t  u8[4];
        }Resp;
        
        Resp.u8[0]=0x7E;
        Resp.u8[1]=gTerminal.u16>>8;//(gTerminal.input.ligado<<7)|(gTerminal.input.tecla_agua<<6)|(gTerminal.input.pressao3<<5)|(gTerminal.input.pressao2<<4)|(gTerminal.input.pressao1<<3)|(gTerminal.input.tempo3<<2)|(gTerminal.input.tempo2<<1)|(gTerminal.input.tempo1);
        Resp.u8[2]=gTerminal.u16;//(gTerminal.input.velocidade3<<2)|(gTerminal.input.velocidade2<<1)|(gTerminal.input.velocidade3);
        Resp.u8[3]=0;
        //delay_ms(20);
        GPIO_SetValue(1,(uint32_t)(1<<31) );
        //terminal_feedback(Resp.u8[0]);
        //delay_ms(1);
        //terminal_feedback(Resp.u8[1]);
        //delay_ms(1);
        //terminal_feedback(Resp.u8[2]);
        //delay_ms(1);

        //UART2Send((LPC_UART_TypeDef *)LPC_UART2,(uint8_t*)&Resp.u8[0],1);
        //UART_Send((LPC_UART_TypeDef *)LPC_UART2, (uint8_t *)&Resp.u8[0], 1, NONE_BLOCKING);
        //UART2Send((LPC_UART_TypeDef *)LPC_UART2,(uint8_t*)&Resp.u8[1],1);
        //UART_Send((LPC_UART_TypeDef *)LPC_UART2, (uint8_t *)&Resp.u8[1], 1, NONE_BLOCKING);  
        //UART_Send((LPC_UART_TypeDef *)LPC_UART2, (uint8_t *)&Resp.u8[2], 1, NONE_BLOCKING);    
        //UART2Send((LPC_UART_TypeDef *)LPC_UART2,(uint8_t*)Resp.u8[0],3); 
        UART_Send((LPC_UART_TypeDef *)LPC_UART2,(uint8_t*)&Resp.u8[0],3, BLOCKING);
        delay_ms(2);
        GPIO_ClearValue(1,(uint32_t)(1<<31) );
        gTerminalFeedBack	=	0;
}

void isr_terminal(void)
{
	uint8_t tmp[3];
	uint16_t value;
	
	if(UART_Receive((LPC_UART_TypeDef *)LPC_UART2,(uint8_t*)tmp,3,BLOCKING)==3)
	{
		if(tmp[0] ==  0x7E)
		{
			if(((tmp[1]&0xC0)==0xC0)&& ((tmp[1]&0x80)==0x80))
			{
				value=(tmp[1]<<8)|(tmp[2]);
				terminal_read(value);
				delay_ms(20);
				terminal_feedback();
			}
		}
	}
}

/**********************************************************************************
 * Descricao:
 *
 * Parametro(s):Finalidade de
 *					-
 * Retorno:
 *					-
 **********************************************************************************/

void terminal_reset(void)
{
	extern union_terminal	sTempTerminal;
	uint8_t ResetTerminal[]={0x7e,0xFF,0xFF};


	gTerminal.u16	=	sTempTerminal.u16;
   	gTerminal.input.ligado	=	0;		//garante que irá deixar desligado o processo

	GPIO_SetValue(1,(uint32_t)(1<<31) );

	UART_Send((LPC_UART_TypeDef *)LPC_UART2, (uint8_t*)ResetTerminal, sizeof(ResetTerminal),BLOCKING);
	
	delay_ms(2);
	GPIO_ClearValue(1,(uint32_t)(1<<31) );
	
}

/**********************************************************************************
 * void AnalisaTeclado(void)
 * Descricao:Monitora a fifo de recebimento para analisar se ocorreu um recebimento
 * do Teclado.
 *
 * Parametro(s):
 *					-
 * Retorno:
 *					-
 **********************************************************************************/
void AnalisaTeclado(void){

	typedef enum {
		eIdleRx,
		ePart1,
		ePart2,
		eAckKeyboard,
		eNackKeyboard,
	}eStateKeyBoard;

	static uint8_t lStateKeyBoard	=	eIdleRx;
	static uint16_t lTempValueKb	=	0;

	uint8_t Keyboard[3]	=	{0,0,0};

	switch (lStateKeyBoard) {
		case eIdleRx:
			if(UART2Receive((LPC_UART_TypeDef *)LPC_UART2,(uint8_t*)&Keyboard[0],1)){
				if(Keyboard[0]	==	0x7E){
					lStateKeyBoard	=	ePart1;
				}
			}
			break;
		case ePart1:
			if(UART2Receive((LPC_UART_TypeDef *)LPC_UART2,(uint8_t*)&Keyboard[1],1)){
				if((Keyboard[1]&0xC0)	==	0xC0){
					lStateKeyBoard	=	ePart2;
					lTempValueKb	=	(uint16_t)(Keyboard[1]<<8);
				}else{
					lStateKeyBoard	=	eNackKeyboard;
				}
			}
			break;
		case ePart2:
			if(UART2Receive((LPC_UART_TypeDef *)LPC_UART2,(uint8_t*)&Keyboard[2],1)){
				if((Keyboard[1]&0x80)	==	0x80){
					lStateKeyBoard	=	ePart2;
					lTempValueKb	|=	(uint16_t)(Keyboard[2]);
				}else{
					lStateKeyBoard	=	eNackKeyboard;
				}
			}
			break;
		case eAckKeyboard:
			gTerminal.u16	=	lTempValueKb;
			lStateKeyBoard	=	eIdleRx;
			break;
		case eNackKeyboard:
			gTerminal.u16	=	0;
			lStateKeyBoard	=	eIdleRx;
			break;
		default:
			lStateKeyBoard	=	eIdleRx;
			break;
	}
}
